<?

function bracket_implode($sep,$a) {
	if (count($a) > 1) {
		return "(".implode($sep,$a).")";
	} else {
		return @$a[0];
	}
}

function getQueryProfile($portal_id,$load_external = false) {
	$query = array();
	$data = getAll("SELECT * FROM filter WHERE portal_id = $portal_id AND status_id = 1 AND value != '' ORDER BY type+0,filter_id");
	if (empty($data)) {
		return $query;
	}
	$any = array();
	$not = array();
	$all = array();
	$query['add'] = $query['substract'] = $query['stats'] = array();
	foreach ($data as $idx => $row) {
		if ($row['type'] == 'any') {
	
			if ($row['profile'] == 'sphinx') {
				$any[] = $row['value'];
				
			} elseif ($row['profile'] == 'text' || $row['profile'] == 'title' || $row['profile'] == 'snippet' || $row['profile'] == 'category') {
				$any[] = $row['profile'].':'.$row['value'];
				
			} elseif ($row['profile'] == 'users') {
				$words = explode(' ',trim(preg_replace('/[^\w]+/',' ',$row['value'])));
				$any[] = "user_id:".bracket_implode('|',$words);
								
			} elseif ($row['profile'] == 'shared') {
				$words = explode(' ',trim(preg_replace('/[^\w]+/',' ',$row['value'])));
				$any[] = "snippet_id:".bracket_implode('|',$words);
								
			} elseif ($row['profile'] == 'grs') {
				$words = explode(' ',trim(preg_replace('/[^\w]+/',' ',$row['value'])));
				$o = $bits = array();
				foreach ($words as $word) {
					switch(strlen($word)) {
						case 6:
						case 5: @$bits['gridref'][] = $word; break;
						case 4:
						case 3: @$bits['hectad'][] = $word; break;
						case 2:
						case 1: @$bits['myriad'][] = $word; break;
					}
				}
				foreach ($bits as $k => $a) {
					$o[] = "$k:".bracket_implode('|',$a);
				}
				$any[] = bracket_implode(' ',$o);
			
			} elseif ($row['profile'] == 'taken') {
				$words = explode(' ',trim(preg_replace('/[^\w]+/',' ',$row['value'])));
				$o = $bits = array();
				foreach ($words as $word) {
					switch(strlen($word)) {
						case 8: @$bits['takenday'][] = $word; break;
						case 6: @$bits['takenmonth'][] = $word; break;
						case 4: @$bits['takenyear'][] = $word; break;
					}
				}
				foreach ($bits as $k => $a) {
					$o[] = "$k:".bracket_implode('|',$a);
				}
				$any[] = bracket_implode(' ',$o);
					
			} elseif ($row['profile'] == 'words') {
				$words = explode(' ',trim(preg_replace('/[^\w]+/',' ',$row['value'])));
				if (count($words) > 10) {
					$any[] = implode(' | ',$words);
				} else {
					$any[] = '"'.implode(' ',$words).'"/1';
				}
				
			} elseif ($row['profile'] == 'phrase') {
				$words = explode(' ',trim(preg_replace('/[^\w]+/',' ',$row['value'])));
				if (count($words) > 1) {
					$any[] = '"'.implode(' ',$words).'"';
				} else {
					$any[] = $words[0];
				}
				
			} elseif ($row['profile'] == 'ids') {
				$query['add'] = array_merge($query['add'],explode(' ',$row['value']));
				
			} elseif ($load_external) {
				//special ones that load external resources - so only load them if really needed!
			
				if ($portal_id == 58) {
					list($ids,$newtags) = loadWikiMediaFile();
					$query['add'] = array_merge($query['add'],$ids);
					$query['newtags'] = $newtags;

				} elseif ($row['profile'] == 'cluster') {

					$query['add'] = array_merge($query['add'],getCol("SELECT gridimage_id FROM geograph_live.gridimage_group WHERE label = ".dbQuote($row['value'])));


				} elseif ($row['profile'] == 'last') {

					$url = "http://www.geograph.org.uk/api/Last?output=json";

					#Get from http://pear.php.net/package/Services_JSON
					require_once $_SERVER['DOCUMENT_ROOT'].'/google/JSON.php';

					$json = new Services_JSON();

					$value = $json->decode(file_get_contents($url));

					if (is_array($value) && count($value) > 0) {

						$query['add'] = array_merge($query['add'],array_values($value));
					}

				} elseif ($row['profile'] == 'potd') {

					$url = "http://www.geograph.org.uk/api/Potd?output=json";

					#Get from http://pear.php.net/package/Services_JSON
					require_once $_SERVER['DOCUMENT_ROOT'].'/google/JSON.php';

					$json = new Services_JSON();

					$value = $json->decode(file_get_contents($url));

					if (is_object($value)) {
						$ids = array();
						$newtags = array();

						foreach ($value as $gid => $day) {
							$ids[] = $gid;
							$newtags[$gid] = array('day'=>$day);
						}
						$query['add'] = array_merge($query['add'],$ids);
						$query['newtags'] = $newtags;
					}

				} elseif ($row['profile'] == 'gurl') {

					if (preg_match('/topic=(\d+)/',$row['value'],$m) 
					|| preg_match('/\/gallery\/.*_(\d+)(\/\d+|)\s*$/',$row['value'],$m)) {

						$url = "http://www.geograph.org.uk/api/Post/{$m[1]}?output=json";

						#Get from http://pear.php.net/package/Services_JSON
						require_once $_SERVER['DOCUMENT_ROOT'].'/google/JSON.php';

						$json = new Services_JSON();

						$value = $json->decode(file_get_contents($url));

						if (is_object($value)) {
							$ids = array();
							foreach ($value as $gid => $count) {
								$ids[] = $gid;
							}
							$query['add'] = array_merge($query['add'],$ids);
						}

					} elseif (preg_match('/article\/([\w-]+)$/',$row['value'],$m)) {

						$url = "http://www.geograph.org.uk/api/Article/{$m[1]}?output=json";

						#Get from http://pear.php.net/package/Services_JSON
						require_once $_SERVER['DOCUMENT_ROOT'].'/google/JSON.php';

						$json = new Services_JSON();

						$value = $json->decode(file_get_contents($url));

						if (is_array($value) && count($value) > 0) {
							$query['add'] = array_merge($query['add'],array_values($value));
						}

					} elseif (preg_match('/\/snippet\/(\d+)/',$row['value'],$m)) {
						$any[] = "snippet_id:{$m[1]}"; //sphinx can do this!
					}

				}
			}
			
		} elseif ($row['type'] == 'all') {
	
			if ($row['profile'] == 'sphinx') {
				$all[] = $row['value'];
				
			} elseif ($row['profile'] == 'text' || $row['profile'] == 'title' || $row['profile'] == 'snippet' || $row['profile'] == 'category') {
				$all[] = $row['profile'].':'.$row['value'];
				
			} elseif ($row['profile'] == 'users') {
				$words = explode(' ',trim(preg_replace('/[^\w]+/',' ',$row['value'])));
				$all[] = "user_id:".bracket_implode('|',$words);
								
			} elseif ($row['profile'] == 'shared') {
				$words = explode(' ',trim(preg_replace('/[^\w]+/',' ',$row['value'])));
				$all[] = "snippet_id:".bracket_implode('|',$words);
								
			} elseif ($row['profile'] == 'grs') {
				$words = explode(' ',trim(preg_replace('/[^\w]+/',' ',$row['value'])));
				$o = $bits = array();
				foreach ($words as $word) {
					switch(strlen($word)) {
						case 6:
						case 5: @$bits['gridref'][] = $word; break;
						case 4:
						case 3: @$bits['hectad'][] = $word; break;
						case 2:
						case 1: @$bits['myriad'][] = $word; break;
					}
				}
				foreach ($bits as $k => $a) {
					$o[] = "$k:".bracket_implode('|',$a);
				}
				$all[] = bracket_implode(' ',$o);
			
			} elseif ($row['profile'] == 'taken') {
				$words = explode(' ',trim(preg_replace('/[^\w]+/',' ',$row['value'])));
				$o = $bits = array();
				foreach ($words as $word) {
					switch(strlen($word)) {
						case 8: @$bits['takenday'][] = $word; break;
						case 6: @$bits['takenmonth'][] = $word; break;
						case 4: @$bits['takenyear'][] = $word; break;
					}
				}
				foreach ($bits as $k => $a) {
					$o[] = "$k:".bracket_implode('|',$a);
				}
				$all[] = bracket_implode(' ',$o);
					
			} elseif ($row['profile'] == 'words') {
				$words = explode(' ',trim(preg_replace('/[^\w]+/',' ',$row['value'])));
				if (count($words) > 10) {
					$all[] = implode(' | ',$words);
				} else {
					$all[] = '"'.implode(' ',$words).'"/1';
				}
				
			} elseif ($row['profile'] == 'phrase') {
				$words = explode(' ',trim(preg_replace('/[^\w]+/',' ',$row['value'])));
				if (count($words) > 1) {
					$all[] = '"'.implode(' ',$words).'"';
				} else {
					$all[] = $words[0];
				}
			}
			
		} elseif ($row['type'] == 'not') {
		
			if ($row['profile'] == 'sphinx') {
				die("unsupported filter");
				$not[] = "-(".$row['value'].")"; //maybe?
				
			} elseif ($row['profile'] == 'users') {
				$words = explode(' ',trim(preg_replace('/[^\w]+/',' ',$row['value'])));
				$not[] = "-user_id:".bracket_implode('|',$words);
								
			} elseif ($row['profile'] == 'shared') {
				$words = explode(' ',trim(preg_replace('/[^\w]+/',' ',$row['value'])));
				$not[] = "-snippet_id:".bracket_implode('|',$words);
								
			} elseif ($row['profile'] == 'grs') {
				$words = explode(' ',trim(preg_replace('/[^\w]+/',' ',$row['value'])));
				$o = $bits = array();
				foreach ($words as $word) {
					switch(strlen($word)) {
						case 6:
						case 5: @$bits['gridref'][] = $word; break;
						case 4:
						case 3: @$bits['hectad'][] = $word; break;
						case 2:
						case 1: @$bits['myriad'][] = $word; break;
					}
				}
				foreach ($bits as $k => $a) {
					$o[] = "$k:".bracket_implode('|',$a);
				}
				$not[] = '-'.bracket_implode(' ',$o);
			
			} elseif ($row['profile'] == 'taken') {
				$words = explode(' ',trim(preg_replace('/[^\w]+/',' ',$row['value'])));
				$o = $bits = array();
				foreach ($words as $word) {
					switch(strlen($word)) {
						case 8: @$bits['takenday'][] = $word; break;
						case 6: @$bits['takenmonth'][] = $word; break;
						case 4: @$bits['takenyear'][] = $word; break;
					}
				}
				foreach ($bits as $k => $a) {
					$o[] = "$k:".bracket_implode('|',$a);
				}
				$not[] = '-'.bracket_implode(' ',$o);
					
			} elseif ($row['profile'] == 'words') {
				$words = explode(' ',trim(preg_replace('/[^\w]+/',' ',$row['value'])));
				$not[] = "-".implode(' -',$words);
				
			} elseif ($row['profile'] == 'phrase') {
				$words = explode(' ',trim(preg_replace('/[^\w]+/',' ',$row['value'])));
				if (count($words) > 1) {
					$not[] = '-"'.implode(' ',$words).'"';
				} else {
					$not[] = '-'.$words[0];
				}
				
			} elseif ($row['profile'] == 'ids') {
				$query['substract'] += explode(' ',$row['value']);
			}
			
		} else {
			die("unsupported filter");
		}
	
	}
	if (count($any)) {
		$query['sphinx'] = bracket_implode(' ) | ( ',$any);
		
		if (count($all) | count($not)) {
			$query['sphinx'] = " ( ".$query['sphinx']." )";
		}
		$query['stats']['any'] = count($any);
	} else {
		$query['sphinx'] = '';
	}
	if (count($all)) {
		$query['sphinx'] .= ' '.implode(' ',$all);
		$query['stats']['all'] = count($all);
	}
	if (count($not)) {
		$query['sphinx'] .= ' '.implode(' ',$not);
		$query['stats']['not'] = count($not);
	}
	if ($query['sphinx']) {
		$query['sphinx'] = trim($query['sphinx']);
	}
	return $query;
}

function addNewImages($portal_id,$limit = 1000) {

	global $CONF;
	
	
	require_once($_SERVER['DOCUMENT_ROOT'].'/geograph/sphinxwrapper.class.php'); 
	
	#$CONF = array();
	$CONF['sphinx_host'] = "tea.geograph.org.uk";
	$CONF['sphinx_port']= 3312;
	$CONF['sphinx_index']= "gi_stemmed,gi_stemmed_delta";
	
	
	$query = getQueryProfile($portal_id,true);
	
	$delta = 0;
	$table = "p2.gridimage{$portal_id}_bi";
	
	if (!empty($query['sphinx'])) {
		
		$q = $query['sphinx'];

		$q = preg_replace('/\b(day|month|year):/','taken$1:',$q);
		$q = preg_replace('/\b(monthname):/','month:',$q);
		$q = preg_replace('/\b(gridref):/','grid_reference:',$q);
		$q = preg_replace('/\b(category):/','imageclass:',$q);
		$q = preg_replace('/\b(description):/','comment:',$q);
		$q = preg_replace('/\b(name):/','realname:',$q);


		//use cursors to loop, rather than traditional paging. Using SetIDRange so need to order by doc_id
		$more = true;
		$min_id = 1;
		$counter =0;
		
		while ($more && $counter < 10) {
			$more = false; //so we have to explicitly enable it if want to go again... 
			
			$sphinx = new sphinxwrapper($q);

			$q = $sphinx->q;

			$pg = (!empty($_GET['page']))?intval(str_replace('/','',$_GET['page'])):0;
			if (empty($pg) || $pg < 1) {$pg = 1;}

			$sphinx->pageSize = $pgsize = min(1000,$limit); //max_matches

			$offset = (($pg -1)* $sphinx->pageSize);

#print  "$pg##$pgsize##$offset##($offset < (1000-$pgsize) )##";

			if ($offset <= (1000-$pgsize) ) { 
				#$sphinx->processQuery();

				$cl = $sphinx->_getClient();
				
				if ($min_id > 1)  {
					$cl->SetIDRange($min_id,999999999);
				}
				
				$sphinx->sort = "@id ASC";

				$ids = $sphinx->returnIds($pg,$CONF['sphinx_index']);	
				if (isset($_GET['d'])) {
					print_rp($q);
					print_rp($cl);
				}

				if (!empty($ids) && count($ids)) {



					//TODO SET status_id, based on portal.approval

					foreach ($ids as $id) {
						$sql = "INSERT INTO $table SET gridimage_id = $id,status_id = 1,created=NOW() ON DUPLICATE KEY UPDATE status_id = 1,updated=NOW()";
						queryExecute($sql);
					}
					
					$delta += count($ids);

					if ($limit > 1000 && count($ids) == 1000) { //we want, and there could be more
						$more = true;
						$min_id = array_pop($ids); //use the last one (we have $sphinx->sort = "@id ASC" :)
					}
				}
				
					
			} else {
				$delta = -1;
			}
			$counter++;
		}
	}
	if (!empty($query['add'])) {
		foreach ($query['add'] as $id) {
			$sql = "INSERT INTO $table SET gridimage_id = $id,status_id = 1,created=NOW() ON DUPLICATE KEY UPDATE status_id = 1,updated=NOW()"; 
			queryExecute($sql);
			
			if (mysql_affected_rows()) {
				$delta++; 
			}
		}
		
		if (!empty($query['newtags'])) {
			//TODO, this could probably be made MUCH more efficient?
			
			$tagtable = "gridimage2tag{$portal_id}_bi";
			
			$user_id = 1; //the system user!
			
			foreach ($query['newtags'] as $gid => $tags) {
				foreach ($tags as $key => $value) {
					$tag_id = getOne("SELECT tag_id FROM `tag` WHERE `display` = ".dbQuote($value));

					if (empty($tag_id)) {
						//need to create it!

						$u = array();
						$u['tag'] = str_replace(' ','-',trim(preg_replace('/[^\w :\-]+/','',strtolower($value)))); //TODO - make unique?
						$u['display'] = $value;
						$u['added_by'] = $user_id;
						$u['created'] = 'NOW()';
						$bits = explode(':',$u['tag']);
						if (count($bits) > 1) {
							$u['prefix'] = $bits[0];
						} elseif (!is_numeric($key)) {
							$u['prefix'] = $key;
						}
						$sql= updates_to_insert('tag',$u);
						queryExecute($sql);

						$tag_id = mysql_insert_id();

						//log the tag
						$u = array();
						$u['table'] = 'tag';
						$u['table_id'] = $tag_id;
						$u['name'] = 'display'; //no point logging all the values? just the display should be enough. 
						$u['value'] = $value;
						$u['user_id'] = $user_id;
						$sql= updates_to_insert('update_log',$u);
						queryExecute($sql);
					}
					
					$u = array();

					$u['gridimage_id'] = $gid;
					$u['tag_id'] = $tag_id;
					$u['added_by'] = $user_id;

					$sql= updates_to_insert($tagtable,$u);

					queryExecute(str_replace('INSERT INTO `grid','INSERT IGNORE INTO `p2`.`grid',$sql));
				
					if (mysql_affected_rows() > 0) {
						//log the gridimage2tag
						$u = array();
						$u['table'] = $tagtable;
						$u['table_id'] = $gid;
						$u['name'] = 'tag_id';
						$u['value'] = $tag_id;
						$u['user_id'] = $user_id;
						$sql= updates_to_insert('update_log',$u);
						queryExecute($sql);
					}
				}
			}
		}
		
	}
	if (!empty($query['substract'])) {
		foreach ($query['substract'] as $id) {
			$sql = "UPDATE $table SET status_id = 5 WHERE gridimage_id = $id"; //does nothing if never added :)
			queryExecute($sql);
			
			if (mysql_affected_rows()) {
				$delta--;
			}
		}
	}	
	
	// - remove outdated images!
	queryExecute("UPDATE $table SET status_id = 5 WHERE status_id = 1 AND updated < DATE_SUB(NOW(),INTERVAL 24 HOUR)");
	

	
	
	
	return $delta;		
}


function loadWikiMediaFile() {
	$ids = array();
	$newtag = array();
	
	$h = fopen("id_to_categories.txt",'r');
	
	$c = 0;
	$header = fgets($h);
	while (!feof($h) && $c < 50000) {
		$line = fgets($h);
		$bits = explode("\t",$line);
#page_title	cl_sortkey	cl_to
#Ambrosden_composite.jpg	 00000000	Ambrosden
#Ambrosden_composite.jpg	 00000000	Images_from_the_Geograph_British_Isles_project_with_broken_templates
#Woodchester_Mansion_-_geograph.org.uk_-_4.jpg	 00000004	Woodchester_Mansion
		
		$gid = $ids[] = intval($bits[1]);
		
		$newtags[$gid][] = trim($bits[2]);
		
		$c++;
	}
	
	
	return array($ids,$newtags);
}
